﻿Imports Runa.UI.Input
Imports Runa.UI.Styles
Imports Runa.UI.Metadata
Imports Microsoft.Xna.Framework
Imports Microsoft.Xna.Framework.Media
Imports Microsoft.Xna.Framework.Graphics
Imports Runa.Resources.ResourceManager

Namespace Global.Runa.UI.Controls

    Public Class VideoClip
        Inherits Image

        Public Event Completed(ByVal sender As Object, ByVal e As EventArgs)

        Private m_dicParameters As New Dictionary(Of String, Object)
        Private m_bBeginPlay As Boolean = False
        Private m_videoPlayer As VideoPlayer

        <XamlAwareAttribute(IsPlainType:=False, ElementName:="Video", Initializer:=GetType(VideoObjectConverter))>
        Public Property Video() As VideoObject

        Public ReadOnly Property Status() As MediaState
            Get
                If Me.m_videoPlayer IsNot Nothing Then
                    Return Me.m_videoPlayer.State
                Else
                    Return MediaState.Stopped
                End If
            End Get
        End Property

        Public ReadOnly Property PlayerReady() As Boolean
            Get
                Return Me.m_videoPlayer IsNot Nothing AndAlso Me.Video IsNot Nothing
            End Get
        End Property

        <XamlAwareAttribute(IsPlainType:=True, ElementName:="IsLooped")>
        Public Property IsLooped() As Boolean
            Get
                If Me.PlayerReady Then
                    Return Me.m_videoPlayer.IsLooped
                Else
                    Return Me.GetInternalPrameter(Of Boolean)("IsLooped")
                End If
            End Get
            Set(value As Boolean)
                If Me.PlayerReady Then
                    Me.m_videoPlayer.IsLooped = value
                End If
                Me.SetInternalPrameter("IsLooped", value)
            End Set
        End Property

        <XamlAwareAttribute(IsPlainType:=True, ElementName:="IsMuted")>
        Public Property IsMuted() As Boolean
            Get
                If Me.PlayerReady Then
                    Return Me.m_videoPlayer.IsMuted
                Else
                    Return Me.GetInternalPrameter(Of Boolean)("IsMuted")
                End If
            End Get
            Set(value As Boolean)
                If Me.PlayerReady Then
                    Me.m_videoPlayer.IsMuted = value
                End If
                Me.SetInternalPrameter("IsMuted", value)
            End Set
        End Property

        <XamlAwareAttribute(IsPlainType:=True, ElementName:="Volume")>
        Public Property Volume() As Single
            Get
                If Me.PlayerReady Then
                    Return Me.m_videoPlayer.Volume
                Else
                    Return Me.GetInternalPrameter(Of Single)("Volume")
                End If
            End Get
            Set(value As Single)
                If Me.PlayerReady Then
                    Me.m_videoPlayer.Volume = value
                End If
                Me.SetInternalPrameter("Volume", value)
            End Set
        End Property

        Public ReadOnly Property PlayPosition() As TimeSpan
            Get
                If Me.PlayerReady Then
                    Return Me.m_videoPlayer.PlayPosition
                Else
                    Return Nothing
                End If
            End Get
        End Property

        Public Sub New(ByVal Parent As UIElementBase)
            MyBase.New("", Parent)
            Me.Name = Me.GetType().Name & "_" & BytesToString(Guid.NewGuid().ToByteArray())
            Me.SizeMode = Controls.SizeMode.Normal
        End Sub

        Public Sub New(ByVal Name As String, ByVal Parent As UIElementBase)
            MyBase.New(Name, Parent)
            Me.SizeMode = Controls.SizeMode.Normal
        End Sub

        Public Sub Play()
            If Me.PlayerReady Then
                Me.m_bBeginPlay = True
                Me.m_videoPlayer.Stop()
                Me.m_videoPlayer.Play(Me.Video.Video)
            End If
        End Sub

        Public Sub Play(ByVal v As Video)
            Me.m_bBeginPlay = True
            Me.m_videoPlayer.Stop()
            Me.Video = New VideoObject() With {.Video = v}
            Me.m_videoPlayer.Play(Me.Video.Video)
        End Sub

        Public Sub Play(ByVal v As VideoObject)
            Me.m_bBeginPlay = True
            Me.m_videoPlayer.Stop()
            Me.Video = v
            Me.m_videoPlayer.Play(Me.Video.Video)
        End Sub

        Public Sub [Stop]()
            If Me.PlayerReady Then
                Me.m_videoPlayer.Stop()
                RaiseEvent Completed(Me, New EventArgs())
            End If
        End Sub

        Public Sub [Resume]()
            If Me.PlayerReady Then
                Me.m_videoPlayer.Resume()
            End If
        End Sub

        Public Sub Pause()
            If Me.PlayerReady Then
                Me.m_videoPlayer.Pause()
            End If
        End Sub

        Protected Overrides Sub Initialize()
            Me.m_videoPlayer = New VideoPlayer()
            MyBase.Initialize()
        End Sub

        Public Overrides Sub Draw(SpriteBatch As Microsoft.Xna.Framework.Graphics.SpriteBatch)
            If Me.m_videoPlayer IsNot Nothing Then
                If Me.m_videoPlayer.State = MediaState.Playing Then
                    Me.Foreground = Me.m_videoPlayer.GetTexture()
                End If
            End If
            MyBase.Draw(SpriteBatch)
        End Sub

        Public Overrides Sub Update(gameTime As Microsoft.Xna.Framework.GameTime)
            If Me.PlayerReady AndAlso Me.m_bBeginPlay Then
                If Me.m_videoPlayer.State = MediaState.Stopped Then
                    RaiseEvent Completed(Me, New EventArgs())
                    Me.m_bBeginPlay = False
                End If
            End If
            MyBase.Update(gameTime)
        End Sub

        Protected Overrides Sub Dispose(disposing As Boolean)
            If m_videoPlayer IsNot Nothing Then
                Me.m_videoPlayer.Stop()
                Me.m_videoPlayer.Dispose()
            End If
            MyBase.Dispose(disposing)
        End Sub

        Private Sub SetInternalPrameter(Of T)(ByVal key As String, ByVal value As T)
            If Me.m_dicParameters.ContainsKey(key) Then
                Me.m_dicParameters(key) = value
            Else
                Me.m_dicParameters.Add(key, value)
            End If
        End Sub

        Private Function GetInternalPrameter(Of T)(ByVal key As String) As T
            If Me.m_dicParameters.ContainsKey(key) Then
                Return GenericCast(Of Object, T)(Me.m_dicParameters(key))
            Else
                Dim obj As T = [Default](Of T)()
                Me.SetInternalPrameter(key, obj)
                Return obj
            End If
        End Function

    End Class

End Namespace